哈囉,我們又見面了,昨天提到了 XSS
、CSRF
、Injection
、Clickjacking
的安全議題,今天繼續深入研究,在 Django
這個以 Python
為主的後端框架,幫我們做了哪些安全議題的防護措施,類此夠 ~ (今天依舊是參考官方文件作為文章大綱)
SSL/HTTPS
不同於前面幾個項目,SSL/HTTPS
不是一種攻擊手法,反而是一種防禦方法,透過加密的傳輸通道,讓我們的資料傳遞過程更加安全。
SSL/HTTPS
SSL
(Secure Sockets Layer) 是一種安全協定,也就是說瀏覽器和網站共同遵守這個協定的話,那麼在瀏覽網站時,傳輸的資料就會受到加密保護,增加駭客要偷走你們資料的難度,目前提到的 SSL 其實是 TLS
(Transport Layer Security),是 SSL
的進化版,但目前講 SSL
都是指 TLS
。
瀏覽器和網站的溝通可以透過 HTTP
(port 80)、也可以透過 HTTPS
(port 443),這兩個在於傳輸資料的安全性不同,現在的網站如果沒有掛 HTTPS
,通常瀏覽器都會警告使用者:「這是不安全的網站」,所以遵守 HTTPS
協定是目前的必備品了。
HTTPS
和 SSL
是什麼關係 ?要解釋這點,需要先科普一下網路結構,一般來說網路分為五層(TCP/IP)或七層(OSI),我們這邊以七層來解釋,HTTPS
在第七層-應用層(Application Layer),而 SSL
在第六層-表達層(Presentation Layer) 進行加密、解密。
還想更深入瞭解的話,可以參考 [Security] SSL — HTTPS 背後的功臣 | Medium。
Django
怎麼做到 SSL/HTTPS
?Django 提供四個設定的步驟,就能將原本的 http
封包轉向 https
,詳細需要設定的項目,參考官方文件,而詳細該怎麼讓 Django
掛上 https
,可以參考 Django部署HTTPS | 掘金。
也就是 驗證 header 內的 host 欄位,源自於 HTTP header injection 的 Host Header Attack,這個攻擊簡單來說,就是透過修改 HTTP request 中的 host
欄位,並且需配合 server 端有 Caching 機制時,把修改過的封包,暫存在 Cache Server 中,那其他不知情的使用者,就會從 Cache Server 抓到被污染(Poisoned)的封包。
host
欄位,會造成什麼影響?駭客可以把 host
改為自己的 server,然後改為執行某一支有危害的 javascript,嚴重性可以到作為釣魚網站,只要能把 host
改為自己的 server 的話,就可能可以執行 上一篇所提到的 XSS 攻擊。
要防止 Host header attack
,就是 不要相信 從使用者發出 request 的欄位,而 Django 替開發者做的是,檢查每個 request 的 host
欄位,是否有在 settings.py
中的 ALLOWED_HOSTS
裡,但這個檢查的功能,只有在你使用 django.http.HttpRequest.get_host()
這個 function 時,才會被檢查,所以如果你不透過 get_host()
這個 function,來讀取 request 中的 host 欄位,那麼 Django 就幫不了你了。
還有一點,Django 預設把 X-Forwarded-Host
選項關掉,如果你要啟用 X-Forwarded-Host
的 header 欄位的話,你必須要在 settings.py
中寫下:
...
USE_X_FORWARDED_HOST = True
...
Referrer policy
?HTTP request 的 header 中,有一個欄位是 Referer
,但其實正確的拼法是 Referrer
,因為早期拼錯了,所以沿用,這故事很瞎吧,竟然還被 wiki 給記錄下來,總之他們兩個是一樣的東西,這個 Referer
的欄位,就是告訴後端 server 說:「我是從 referer 這個欄位的網站,連到你的網站的」,上圖所顯示的就是,我從 google 搜尋連到 iT 邦幫忙首頁,所以 Referer
欄位就是 google。
而 Referrer policy
指的是,在傳送 request 的時候,要放多少 referrer
的資訊在裡頭,可以詳細放到是哪個 domain 的某個網頁、也可以只放 domain、也可以什麼都不放。
Referrer policy
?Django 預設有的 SecurityMiddleware
,你可以透過在 settings.py
設定 SECURE_REFERRER_POLICY
變數,來告訴 SecurityMiddleware
該怎麼制定 Referrer policy,詳細可以參考官方文件。
Session
(會話),你可以把它想成兩個人之間的一次對話,兩個人這次見面聊完了就算一個 Session
結束,而下次再見面就是不同的 Session
,那麼用在網路上,一個 Session
就是使用者造訪了某一個網站,然後做了一些行為,可能是登入、結帳等等,都會記錄在 Session
中。
例如攻擊者可以利用 cookies
的機制,在一個正常的子網域底下正常登入,攻擊者打下了另一個子網域,然後把這個攻擊者登入的 cookies
傳送給無辜的使用者,而使用者無意間就用了攻擊者的帳號登入了,萬一在這樣的情況下,使用攻擊者的帳號輸入了自己重要的資訊,就被攻擊者竊取成功。
聽起來很繞口,參考官方文件舉的例子應該會比較好懂 XD
Django 預設有 SessionMiddleware
,會幫你把使用者的 cookies 記錄下來,cookies 包含了 session ID,會存在 DB 裡的 django_session
表格中,詳細的 session 可以參考官方文件。
簡單來講,就是不要相信使用者傳上來的資料,作為一個稱職的後端,必須好好檢查從使用者接過來的資料、欄位或檔案,從這兩天的例子可以觀察出,很多時候的安全漏洞,都是後端沒有好好檢查從使用者傳來的資料發生的,像是 SQL Injection
就是沒有檢查資料、像 Host header attack 就是沒有檢查 host
欄位等等。
官方列了六點,我大致翻譯一下:
settings.py
裡的 SECRET_KEY
別外洩OWASP
公布的前十危險的網站弱點終於把這系列文件 K 完了 QQ,也算是多學習好幾種的攻擊手法跟防禦方法,還有框架能替開發者做的防護有哪些,K 完之後有點像是一個大補帖的概念,會瞬間覺得自己好像懂了點什麼哈哈,可是實際在網安的概念都還是太弱了,繼續加油~
明天就是這系列的最後一天了,想好好整理一下經過這三十天,從 Android 轉學習後端的綜合感想,以及未來的走向。
今天是禮拜四,好想工作室固定下午都有「想知道嗎」的講座,創辦人 Howard
今天分享了一個主題:「自學的重要性」,提到設定學習目標有兩種,一種是 加法 的目標設定,一種是 減法 的目標設定,像我在這系列所訂定的目標就是屬於 減法 類的,每寫完一篇就扣一,直到寫完三十篇就算完結,這種 減法 的目標有風險,因為你可能挑戰完了,你就失去了目標,進而停止前進,明天的完結篇再來好好聊聊目標訂定的哲學。
我是 RS,這是我的 不做怎麼知道系列 文章,我們 明天見。